using System;
using System.Collections.Generic;
using System.Text;
using MoEngine;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using MoGameLib.Resource.Strings;
using MoGameLib.WindowBattleStates;

namespace MoGameLib
{
    public class WindowBattle : Window
    {
        private Battle m_Battle;
        private WindowBattleMap m_MapWindow;
        private Button m_BtnNextTurn;

        public WindowBattle(WindowBase parent, Battle battle)
            : base(parent)
        {
            m_Battle = battle;
            m_MapWindow = new WindowBattleMap(this);
            m_MapWindow.Board = battle.Map;
            m_MapWindow.MapPicked += new MapPickEvent(BattleMapPicked);
            m_BtnNextTurn = new Button(this, Core.Content.Load<Texture2D>("Images/GUI/Buttons/ButtonNextTurn"));
            m_BtnNextTurn.Layout.SetRight(1, -64);
            m_BtnNextTurn.Layout.SetBottom(1, -64);
            m_BtnNextTurn.Layout.SetWidth(0, 48, true);
            m_BtnNextTurn.Layout.SetHeight(0, 48, true);
            m_BtnNextTurn.Click += new EventHandler<InputEventArgs>(OnBtnNextTurnClick);
        }


        //private bool m_bSkipOrderPhase = false;

        protected override void InitWindowStates()
        {
            base.InitWindowStates();

            StateMgr.AddState(new StateNone(), this);
            StateMgr.AddState(new StateGivingOrders(), this);
            StateMgr.AddState(new StateRunning(), this);

        }


        //private BattlePawn FocusedPawn;

        public virtual void StartOrderPhase()
        {

            // select the battler
            //FocusedPawn = pawn;

            // show a battle cry
            //ShowBattleCry(battler, "", gameTime);
            StateMgr.GotoState(typeof(WindowBattleStates.StateGivingOrders));
        }
        /*
        private double m_BattleCryShowTime;
        private bool m_bShowBattleCry;
        private string m_BattleCry;
        protected virtual void ShowBattleCry(Battler battler, string battleCry, GameTime gameTime)
        {
            m_BattleCryShowTime = gameTime.TotalGameTime.TotalSeconds;
            m_bShowBattleCry = true;
            m_BattleCry = battleCry;
        }

        protected virtual void HideBattleCry(GameTime gameTime)
        {
            m_bShowBattleCry = false;
        }

        protected virtual void DrawBattleCry(SpriteBatch spriteBatch, GameTime gameTime)
        {
            // draw dialog overlay
            float percent = MathHelper.Clamp((float)(gameTime.TotalGameTime.TotalSeconds - m_BattleCryShowTime) / 0.2f, 0, 1);
            Rectangle source = new Rectangle(0, 0, m_ImageDialogOverlay.Width, m_ImageDialogOverlay.Height);
            int full_height = (int)(m_ImageDialogOverlay.Height * ((float)DrawRect.Width / m_ImageDialogOverlay.Width));
            Rectangle dest = new Rectangle(DrawRect.X, DrawRect.Bottom - (int)(full_height), DrawRect.Width, full_height);
            byte alpha = (byte)(255 * percent);
            m_SpriteBatch.Draw(m_ImageDialogOverlay, dest, source, new Color(255, 255, 255, alpha));
            alpha = (byte)(255 * MathHelper.Clamp((float)(gameTime.TotalGameTime.TotalSeconds - m_BattleCryShowTime - 0.15f) / 0.2f, 0, 1));
            m_SpriteBatch.DrawString(m_FontDialog, "[Swordsman]", new Vector2(DrawRect.X + 300, DrawRect.Bottom - 130), new Color(255, 197, 129, alpha));
            m_SpriteBatch.DrawString(m_FontDialog, MoGameStrings.BattleCry, new Vector2(DrawRect.X + 300, DrawRect.Bottom - 100), new Color(250, 255, 220, alpha), 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);
            m_SpriteBatch.DrawString(m_FontDialog, "Press left mouse button to continue (Attack), \n or right button to give order", new Vector2(DrawRect.Right - 400, DrawRect.Bottom - 40), 
                new Color(160, 214, 252, alpha), 0, Vector2.Zero, 0.6f, SpriteEffects.None, 0);
        }*/

        protected Texture2D m_ImageDialogOverlay;
        protected SpriteFont m_FontDialog;
        protected SpriteFont m_FontToolTip;
        protected SpriteFont m_FontNamePlate;

        protected WindowStyle m_Style;

        protected Texture2D m_ImageStageBack;
        protected Texture2D m_ImageIdleBack;

        protected Texture2D m_ImageSigilFriendly;
        protected Texture2D m_ImageSigilEnemy;

        protected Texture2D m_ImagePawnFocus;

        protected override void LoadContent()
        {
            base.LoadContent();

            m_ImageDialogOverlay = Core.Content.Load<Texture2D>("Images/GUI/BattleInfoPanel");
            m_FontDialog = Core.Content.Load<SpriteFont>("Fonts/HuaKangShao");
            m_FontDialog.Spacing = 2;
            //m_FontToolTip = Core.Content.Load<SpriteFont>("Fonts/HuaKangShaoSmall");
            //m_FontNamePlate = Core.Content.Load<SpriteFont>("Fonts/HuaKangShaoLarge");
            m_Style = new WindowStyle(Core.Content.Load<Texture2D>("Images/GUI/DialogStyle"), new Rectangle(32, 32, 192, 192));
            m_ImageStageBack = Core.Content.Load<Texture2D>("Images/GUI/BattleStageFrame");
            m_ImageIdleBack = Core.Content.Load<Texture2D>("Images/GUI/BattleIdleFrame");

            m_ImageSigilFriendly = Core.Content.Load<Texture2D>("Images/Faction/Sigils/Power");
            m_ImageSigilEnemy = Core.Content.Load<Texture2D>("Images/Faction/Sigils/Monster");
            m_ImagePawnFocus = Core.Content.Load<Texture2D>("Images/GUI/IconFocus");
        }

        const float Scale = 0.8f;

        const int StageWidth = (int)(1024 * Scale);
        const int StageHeight = (int)(192 * Scale);
        const int StageCount = 4;

        const int IdleWidth = (int)(192 * Scale);
        const int IdleHeight = (int)(768 * Scale);
        const int MarginIdleToStage = (int)(64 * Scale);
        const int OffsetIdleTop = (int)(64 * Scale);
        const int OffsetStageTop = (int)(64 * Scale);

        const int SigilWidth = (int)(120 * Scale);
        const int SigilHeight = (int)(144 * Scale);

        const int MarginIdleIconTop = (int)(84 * Scale);
        const int MarginIdleIconBetween = (int)(16 * Scale);

        const int PawnIconSize = (int)(64 * Scale);
        const int PawnFocusSize = (int)(96 * Scale);

        readonly Color PawnFocusColor = new Color(109,255,116);

        protected override void DrawWindow(GameTime time)
        {
            base.DrawWindow(time);
/*

            int mid = DrawRect.X + DrawRect.Width / 2;

            Rectangle rectStages = new Rectangle(mid - StageWidth / 2, OffsetStageTop, StageWidth, StageHeight * StageCount);
            Rectangle rectLeftIdle = new Rectangle(rectStages.X - MarginIdleToStage - IdleWidth, OffsetIdleTop, IdleWidth, IdleHeight);
            Rectangle rectRightIdle = new Rectangle(rectStages.Right + MarginIdleToStage, OffsetIdleTop, IdleWidth, IdleHeight);
            Rectangle rectLeftSigil = new Rectangle(rectLeftIdle.X + rectLeftIdle.Width / 2 - SigilWidth / 2, 0, SigilWidth, SigilHeight);
            Rectangle rectRightSigil = new Rectangle(rectRightIdle.X + rectRightIdle.Width / 2 - SigilWidth / 2, 0, SigilWidth, SigilHeight);

            BeginDraw();

            Device.Clear(Color.Black);

            m_SpriteBatch.Draw(m_ImageIdleBack, rectLeftIdle, Color.White);
            m_SpriteBatch.Draw(m_ImageIdleBack, rectRightIdle, Color.White);

            for (int i = 0; i < StageCount; i++)
            {
                Rectangle rectStage = new Rectangle(rectStages.X, rectStages.Y + i * StageHeight, StageWidth, StageHeight);
                m_SpriteBatch.Draw(m_ImageStageBack, rectStage, Color.White);
            }

            m_SpriteBatch.Draw(m_ImageSigilFriendly, rectLeftSigil, Color.White);
            m_SpriteBatch.Draw(m_ImageSigilEnemy, rectRightSigil, Color.White);

            // draw idle pawns

            // left
            //Rectangle rectIdleIcon = new Rectangle(rectLeftIdle.X + rectLeftIdle.Width / 2 - PawnIconSize / 2, rectLeftIdle.Top + MarginIdleIconTop, PawnIconSize, PawnIconSize);
            Point ptPawnIcon = new Point(rectLeftIdle.X + rectLeftIdle.Width / 2, rectLeftIdle.Top + MarginIdleIconTop + PawnIconSize / 2);

            foreach (BattlePawn pawn in m_Battle.IdlePawns(BattleSide.Left))
            {
                DrawPawnIcon(pawn, ptPawnIcon);
                ptPawnIcon.Y += PawnIconSize + MarginIdleIconBetween;
            }

            // right
            ptPawnIcon = new Point(rectRightIdle.X + rectRightIdle.Width / 2, rectRightIdle.Top + MarginIdleIconTop + PawnIconSize / 2);

            foreach (BattlePawn pawn in m_Battle.IdlePawns(BattleSide.Right))
            {
                DrawPawnIcon(pawn, ptPawnIcon);
                ptPawnIcon.Y += PawnIconSize + MarginIdleIconBetween;
            }

            m_SpriteBatch.DrawString(m_FontDialog, MoGameStrings.PromptWaitingForOrder, new Vector2(rectStages.X + 100, rectStages.Bottom + 50), new Color(250, 255, 220, 255), 0, Vector2.Zero, 0.8f, SpriteEffects.None, 0);

            EndDraw();*/
        }
/*
        protected void DrawPawnIcon(BattlePawn pawn, Point cen)
        {
            if (pawn == FocusedPawn)
            {
                Rectangle rectFocus = new Rectangle(cen.X - PawnFocusSize/2, cen.Y - PawnFocusSize/2, PawnFocusSize, PawnFocusSize);
                m_SpriteBatch.Draw(m_ImagePawnFocus, rectFocus, PawnFocusColor);
            }


            Rectangle rectIcon = new Rectangle(cen.X - PawnIconSize/2, cen.Y - PawnIconSize/2, PawnIconSize, PawnIconSize);
            m_SpriteBatch.Draw(pawn.Icon, rectIcon, Color.White);            

        }*/

        /*

        protected override void PostDrawWindow(GameTime time)
        {
            BeginDraw();

            if (m_bShowBattleCry)
                DrawBattleCry(m_SpriteBatch, time);

            //m_Style.Draw(m_SpriteBatch, new Rectangle(DrawRect.X + 100, DrawRect.Bottom - 300, 300, 200));

            EndDraw();

            base.PostDrawWindow(time);
        }*/

        protected StateManager<WindowBattleState> StateMgr = new StateManager<WindowBattleState>();

        public override BaseWindowState CurrentState
        {
            get { return CurrentWindowBattleState; }
        }

        public virtual WindowBattleState CurrentWindowBattleState
        {
            get { return StateMgr.CurrentState; }
        }

        void BattleMapPicked(MapPickEventArgs evtArgs)
        {
            if (CurrentWindowBattleState != null)
                CurrentWindowBattleState.OnMapPicked(evtArgs);
        }

        private Battler m_SelectedBattler;

        public Battler SelectedBattler
        {
            get { return m_SelectedBattler; }
            set 
            { 
                m_SelectedBattler = value;
                m_MapWindow.SelectBattler(value);
            }
        }

        void OnBtnNextTurnClick(object sender, InputEventArgs e)
        {
            if (CurrentState.GetType() == typeof(StateGivingOrders))
            {
                Console.WriteLine("turn has started!!!");
                StateMgr.GotoState(typeof(StateRunning));
                m_Battle.Run();
            }
            else if (CurrentState.GetType() == typeof(StateRunning))
            {
                Console.WriteLine("pause the battle!!!");
                m_Battle.Pause();
            }
        }
    }

    // ---------  window state code ------------//

    #region State Code
    
    public class WindowBattleState : WindowState<WindowBattle>
    {
        public virtual void OnMapPicked(MapPickEventArgs evtArgs) { }
    }

    namespace WindowBattleStates
    {
        internal class StateNone : WindowBattleState { }

        internal class StateRunning : WindowBattleState { }

        internal class StateGivingOrders : WindowBattleState
        {
            public override void Update(GameTime gameTime)
            {
                base.Update(gameTime);

                /*
                if (m_bSkipOrderPhase)
                {
                    // notify battle : end order phase
                    GotoState((int)WindowBattleStates.None);
                }
                else
                {
                    GotoState((int)WindowBattleStates.GivingOrders);
                }*/
            }

            public override void OnMouseDown(MouseButtons button, Point mousePos, InputEventArgs evtArgs)
            {
                /*
                base.OnMouseDown(button, mousePos, evtArgs);
                if (button == MouseButtons.Left)
                {
                    m_bSkipOrderPhase = true;
                }
                else if (button == MouseButtons.Right)
                {
                    m_bSkipOrderPhase = false;
                }
                else
                {
                    return;
                }

                HideBattleCry(evtArgs.Time);*/
            }

            public override void OnMapPicked(MapPickEventArgs evtArgs)
            {
                base.OnMapPicked(evtArgs);

                if (evtArgs.Button == MouseButtons.Left && evtArgs.Battler != null)
                {
                    Window.SelectedBattler = evtArgs.Battler;
                }
                else if (evtArgs.Button == MouseButtons.Right && Window.SelectedBattler != null)
                {
                    if (evtArgs.Battler != null)
                        Window.SelectedBattler.OrderAttack(evtArgs.Battler);
                    else if (evtArgs.Tile != null)
                        Window.SelectedBattler.OrderMove(evtArgs.Tile);
                }
            }

            public override void EndState(State nextState)
            {
                base.EndState(nextState);

                Window.SelectedBattler = null;
            }
        }
    }

    #endregion
}
